/*
 * @Author: hcluo
 * @Date: 2020-04-26 22:21:50
 * @LastEditors: hcluo
 * @LastEditTime: 2020-05-06 20:44:58
 * @Description: 政府项目
 */
import { useEffect, useCallback, useState } from 'react';
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
import {
  GENERAL_FETCH_DATA_BEGIN,
  GENERAL_FETCH_DATA_SUCCESS,
  GENERAL_FETCH_DATA_FAILURE,
  GENERAL_FETCH_DATA_DISMISS_ERROR,
} from './constants';
import { requests } from '../../common/request';

export function fetchData(code, args = {}) {
  return (dispatch) => { // optionally you can have getState as the second argument
    dispatch({
      type: GENERAL_FETCH_DATA_BEGIN,
      code
    });

    const promise = new Promise((resolve, reject) => {
      const doRequest = requests.fetchData(code, { params: args })

      doRequest.then(
        (res) => {
          dispatch({
            type: GENERAL_FETCH_DATA_SUCCESS,
            data: res,
            code
          });
          resolve(res);
        },
        // Use rejectHandler as the second argument so that render errors won't be caught.
        (err) => {
          dispatch({
            type: GENERAL_FETCH_DATA_FAILURE,
            data: { error: err },
            code
          });
          reject(err);
        },
      );
    });

    return promise;
  };
}

export function dismissFetchDataError() {
  return {
    type: GENERAL_FETCH_DATA_DISMISS_ERROR,
  };
}

export function useFetchData(code) {
  const dispatch = useDispatch();

  const { module, request } = useSelector(
    state => ({
      module: state.general.modules[code] || {},
      request: state.general.request[code] || {},
    })
  );




  const boundAction = useCallback((...args) => {
    return dispatch(fetchData(code, ...args)).then(res => {
      console.log('%c 🥕 res: ', 'font-size:20px;background-color: #EA7E5C;color:#fff;', res);
    }).catch(error => {
      console.error('%c 🥃 error: ', 'font-size:20px;background-color: #7F2B82;color:#fff;', error);
    })
  }, [dispatch, code]);

  const boundDismissError = useCallback(() => {
    return dispatch(dismissFetchDataError());
  }, [dispatch]);

  useEffect(() => {
    boundAction(request.params)
    return () => {
    }
  }, [boundAction, request.params])

  return {
    module,
    request,
    status: request.status,
    fetchData: boundAction,
    dismissFetchDataError: boundDismissError,
  };
}

export function reducer(state, action) {
  switch (action.type) {
    case GENERAL_FETCH_DATA_BEGIN:
      // Just after a request is sent
      {
        let request = state.request[action.code] || {}
        request.status = "loading"
        state.request[action.code] = request
        return {
          ...state,
        };
      }
    case GENERAL_FETCH_DATA_SUCCESS:
      // The request is success
      {
        let status = "show"
        let request = state.request[action.code] || {}
        request.status = status
        request.data = action.data

        return {
          ...state,
        };
      }
    case GENERAL_FETCH_DATA_FAILURE:
      // The request is failed
      return {
        ...state,
        // fetchDataPending: false,
        // fetchDataError: action.data.error,
      };

    case GENERAL_FETCH_DATA_DISMISS_ERROR:
      // Dismiss the request failure error
      return {
        ...state,
        // fetchDataError: null,
      };

    default:
      return state;
  }
}
